<?php
/**
 * 易支付
 */

namespace app\admin\service;

use think\facade\Request;

class Yipay
{
    public function createPaymentOrder($paymentRow, $orderdata,$result_type)
    {
        $pay_url = $paymentRow['pay_url']."/".$result_type.".php";
        $orderdata["pid"] = $paymentRow['appid'];
        $orderdata["notify_url"] = Request::domain() . "/admin/block/yipay_server_back";
        if($result_type == "mapi"){
            $orderdata["clientip"] = get_real_ip();
        }
        if($result_type != "mapi"){
            $orderdata["return_url"] = Request::domain() . "/admin/block/yipay_server_back";
        }
        //对数组排序
        $para_sort = $this->argSort($orderdata);
        //生成签名结果
        $sign = $this->buildRequestMysign($para_sort,$paymentRow["private_key"]);
        //将签名放到数组
        $orderdata["sign"] = $sign;
        $orderdata["sign_type"] = "MD5";
        $curl = new HttpRequest($pay_url);
        $result = $curl->send($orderdata);
        $result = json_decode($result, true);
        return $result; 
    }

    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    public function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }

    /**
     * 生成签名结果
     * @param $para_sort 已排序要签名的数组
     * return 签名结果字符串
     */
    public function buildRequestMysign($para_sort,$private_key) {
        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);
        $mysign = $this->md5Sign($prestr, $private_key);
        return $mysign;
    }

    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para 需要拼接的数组
     * return 拼接完成以后的字符串
     */
    public function createLinkstring($para) {
        $arg  = "";
        foreach ($para as $key=>$val) {
            $arg.=$key."=".$val."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,-1);
        return $arg;
    }

    /**
     * 签名字符串
     * @param $prestr 需要签名的字符串
     * @param $key 私钥
     * return 签名结果
     */
    public function md5Sign($prestr, $key) {
        $prestr = $prestr . $key;
        return md5($prestr);
    }

    /**
     * 除去数组中的空值和签名参数
     * @param $para 签名参数组
     * return 去掉空值与签名参数后的新签名参数组
     */
    public function paraFilter($para) {
        $para_filter = array();
        foreach ($para as $key=>$val) {
            if($key == "sign" || $key == "sign_type" || $key == "_input_charset" || $val == "")continue;
            else $para_filter[$key] = $para[$key];
        }
        return $para_filter;
    }

    /**
     * 验证签名
     * @param $prestr 需要签名的字符串
     * @param $sign 签名结果
     * @param $key 私钥
     * return 签名结果
     */
    public function md5Verify($prestr, $sign, $key) {
        $prestr = $prestr . $key;
        $mysgin = md5($prestr);
        if($mysgin == $sign) {
            return true;
        }
        else {
            return false;
        }
    }

    //验证签名
    public function getEpaySignVeryfy($para_temp,$sign,$key) {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = $this->paraFilter($para_temp);
        //对待签名参数数组排序
        $para_sort = $this->argSort($para_filter);
        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);
        $isSgin = false;
        $isSgin = $this->md5Verify($prestr,$sign,$key);
        return $isSgin;
    }
}